
<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <title>NESASM</title>
    <style>
    html,body{font-size:14px; color:#444;} 
    a {text-decoration: none; color:blue;}
    a:hover{color:red;}
    .main{margin:0 auto; width:960px;}
    .box{border:1px solid #eee;}
    </style>
</head>

<body>

<div class="main">
<p>【发生了什么？】
</p><p>嗯，你是个NES小白程序员，今天我们将学习一个NESASM代码文件的结构。不幸的是，我们的汇编器对缩进非常讲究，一行的开始位置只能放标签，放其他所有内容都必须加一个【TAB】键缩进。尽管这样听上去很糟糕，但这样确实提高了可读性，让你更容易理解代码，尤其是大程序。
</p><p>【关于段（Bank）】
</p><p>不不不，Bank不会帮你拿着你的钱，它们帮你拿着你的程序和数据。我们将经常用三个段：
</p><p>段 0 —— 放我们的代码，起始于$8000
</p><p>段 1 —— 中断向量表，很重要，起始于$FFFA
</p><p>段 2 —— 我们将主角和背景数据点阵信息放在这里，起始于$0000
</p><p>我不确定一共有多少段，但显然至少3个。我们将用.bank指令来移动段，用.org指令来告诉汇编器在那个段我们的起始地址是什么。
</p><p>【INES文件头】
</p><p>INES文件头放在每个ROM文件的开头，告诉模拟器一些信息，它们是：
</p><p>.inesprg —— 告诉模拟器有多少个代码段
</p><p>.ineschr —— 告诉模拟器有多少图片数据段
</p><p>.inesmir —— 告诉模拟器……我忘了是什么，但总是1
</p><p>.inesmap —— 我们总是用Mapper 0
</p><p>我们常用设置为：
</p><p>    .inesprg 1   ; 一个代码段
</p><p>    .ineschr 1   ; 一个数据段
</p><p>    .inesmap 0   ; 使用mapper 0
</p><p>    .inesmir 1   ; 总是1
</p><p>这四行将放在（几乎所有）代码文件的最前面。
</p><p>【段0和.org】
</p><p>我们使用段0来放代码，起始地址为$8000。代码将这么写：
</p><p>    .bank 0   ; 段 0.
</p><p>    .org $8000  ; 去 $8000.
</p><p>    ; 真正代码从这里开始
</p><p>就这么多。注意分号（；）后面的内容为注释，汇编器忽略一行分号后面的所有内容。
</p><p>【段1和三个中断向量】
</p><p>不用长篇大论，直接来点美味小吃代码如何？
</p><p>    .bank 1     ; 切到段 1
</p><p>    .org $FFFA  ; 从 $FFFA开始
</p><p>    .dw 0        ; NMI中断向量
</p><p>    .dw Start    ; 复位向量，复位时从这个地址开始运行代码,我们给出了Start标签的地址，该标签最终放在段0中
</p><p>    .dw 0        ; VBlank 中断向量，目前我们不需要
</p><p>段1内容就这么多，简单！
</p><p>【段2和图片数据】
</p><p>段2，我们将从地址$0000开始，里面包含我们的图片数据，可用于背景和主角显示。代码如下：
</p><p>    .bank 2        ; 切到段 2
</p><p>    .org $0000    ; 从 $0000开始
</p><p>    .incbin "our.bkg"  ; 包含二进制文件，内容为我们的背景图片数据
</p><p>    .incbin "our.spr"  ; 包含二进制文件，内容为我们的主角图片数据
</p><p>【今天内容复习】
</p><p>今天真的就这么多。我觉得有点慢了，因为NES编程相对GBA有点痛苦。明天我们会弄明白更多内容。明儿见！
</p></div>
</body>
</html>
